/**
 * 
 */
package uk.ac.manchester.tewpl.iceiface.client.model;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import uk.ac.manchester.tewpl.iceiface.client.util.StringUtil;

import com.extjs.gxt.ui.client.data.BaseModelData;
import com.google.gwt.user.client.rpc.IsSerializable;

/**
 * @author roland
 * 
 */
public class KBResourceModel extends BaseModelData implements IsSerializable,
		Comparable<KBResourceModel> {
	/**
	 * 
	 */
	private static final long serialVersionUID = 9099375259612203560L;
	public static final String KB = "kb";
	public static final String URI = "uri";
	public static final String NAMESPACE = "namespace";
	public static final String LOCALPART = "localpart";

	public static final String LABEL = "label";
	public static final String LABELS = "labels";
	public static final String SOURCE = "source";
	public static final String SOURCES = "sources";
	public static final String COMMENT = "comment";
	public static final String COMMENTS = "comments";
	public static final String DESCRIPTION = "description";
	public static final String DESCRIPTIONS = "descriptions";
	public static final String CREATOR = "creator";
	public static final String CREATORS = "creators";
	public static final String ANNOTATION = "annotation";
	public static final String ANNOTATIONS = "annotations";
	public static final String VERSIONINFOS = "versionInfos";
	public static final String VERSIONINFO = "versionInfo";

	public KBResourceModel() {
		set(LABELS, new HashSet<KBAnnotationValueModel>());
		set(SOURCES, new HashSet<KBAnnotationValueModel>());
		set(CREATORS, new HashSet<KBAnnotationValueModel>());
		set(COMMENTS, new HashSet<KBAnnotationValueModel>());
		set(DESCRIPTIONS, new HashSet<KBAnnotationValueModel>());
		set(VERSIONINFOS, new HashSet<KBAnnotationValueModel>());
		set(ANNOTATIONS, new HashSet<KBAnnotationValueModel>());

	}

	public void setUri(String uri) {
		// System.out.println(uri);
		set(URI, uri);
		set(NAMESPACE, getNamespace(uri));
		set(LOCALPART, getLocalPart(uri));
		// System.out.println("Namespace: " + get(NAMESPACE) + ", LP: " +
		// get(LOCALPART));
	}

	/**
	 * @return the labels
	 */
	public Collection<KBAnnotationValueModel> getLabels() {
		return get(LABELS);
	}

	public String getLabel() {
		String label = get(LABEL);
		if (label != null)
			return label.trim();
		else
			return label;
	}
	
	public String toString(){
		return getLabel();
	}

	/**
	 * @param labels
	 *            the labels to set
	 */
	public void setLabels(Collection<KBAnnotationValueModel> labels) {
		set(LABELS, labels);
		String label = null;
		if (labels.size() > 0)
			label = labels.iterator().next().getValue();

		set(LABEL, StringUtil.isEmpty(label) ? getLocalPart() : label);
		// System.out.println(get(LABEL));
	}

	/**
	 * @return the comments
	 */
	public Collection<KBAnnotationValueModel> getComments() {
		return get(COMMENTS);
	}

	public String getComment() {
		return get(COMMENT);
	}

	/**
	 * @param comments
	 *            the comments to set
	 */
	public void setComments(Collection<KBAnnotationValueModel> comments) {
		set(COMMENTS, comments);
		if (comments.size() > 0)
			set(COMMENT, comments.iterator().next().getValue());
	}

	/**
	 * @return the creators
	 */
	public Collection<KBAnnotationValueModel> getCreators() {
		return get(CREATORS);
	}

	public String getCreator() {
		return get(CREATOR);
	}

	/**
	 * @param creators
	 *            the creators to set
	 */
	public void setCreators(Collection<KBAnnotationValueModel> creators) {
		set(CREATORS, creators);
		if (creators.size() > 0)
			set(CREATOR, creators.iterator().next().getValue());
	}

	/**
	 * @return the descriptions
	 */
	public Collection<KBAnnotationValueModel> getDescriptions() {
		return get(DESCRIPTIONS);
	}

	public String getDescription() {
		return get(DESCRIPTION);
	}

	/**
	 * @param descriptions
	 *            the descriptions to set
	 */
	public void setDescriptions(Collection<KBAnnotationValueModel> descriptions) {
		set(DESCRIPTIONS, descriptions);
		if (descriptions.size() > 0)
			set(DESCRIPTION, descriptions.iterator().next().getValue());

	}

	/**
	 * @return the sources
	 */
	public Collection<KBAnnotationValueModel> getSources() {
		return get(SOURCES);
	}

	public String getSource() {
		return get(SOURCE);
	}

	/**
	 * @param sources
	 *            the sources to set
	 */
	public void setSources(Collection<KBAnnotationValueModel> sources) {
		set(SOURCES, sources);
		if (sources.size() > 0)
			set(SOURCE, sources.iterator().next().getValue());
	}

	/**
	 * @return the versionInfos
	 */
	public Collection<KBAnnotationValueModel> getVersionInfos() {
		return get(VERSIONINFOS);
	}

	/**
	 * @param versionInfos
	 *            the versionInfos to set
	 */
	public void setVersionInfos(Collection<KBAnnotationValueModel> versionInfos) {
		set(VERSIONINFOS, versionInfos);
		if (versionInfos.size() > 0)
			set(VERSIONINFO, versionInfos.iterator().next().getValue());
	}

	public String getVersionInfo() {
		return get(VERSIONINFO);
	}

	public Collection<KBAnnotationValueModel> getAnnotationValues() {
		return get(ANNOTATIONS);
	}

	public void setAnnotationValues(
			Collection<KBAnnotationValueModel> annotations) {
		set(ANNOTATIONS, annotations);
		for (KBAnnotationValueModel a : annotations) {
			a.set(KBAnnotationValueModel.ANNOTATION, getLocalPart(a
					.getAnnotationUri()));
		}
	}

	// /**
	// * @return the annotations
	// */
	// public Map<String, Collection<KBAnnotationValueModel>> getAnnotations() {
	// return get(ANNOTATIONS);
	// }
	//
	// /**
	// * @param annotations
	// * the annotations to set
	// */
	// public void setAnnotations(
	// Map<String, Collection<KBAnnotationValueModel>> annotations) {
	// set(ANNOTATIONS, annotations);
	// if (annotations != null)
	// System.out.println("Setting annotations " + annotations.size());
	// else
	// System.out.println("Annotations is null");
	// // Modify each entry so the annotation values by themselves hold a
	// // reference to the annotation
	// if (annotations != null) {
	// for (String a : annotations.keySet()) {
	// for (KBAnnotationValueModel v : annotations.get(a)) {
	// v.set(ANNOTATION, KBClassModel.getLocalPart(a));
	// v.set(ANNOTATION + "_model", a);
	// }
	// }
	// }
	// }

	public String getNamespace() {
		return get(NAMESPACE);
	}

	public String getLocalPart() {
		String lp = get(LOCALPART);
		return StringUtil.isEmpty(lp) ? "" : lp;
	}

	public void setLocalPart(String localPart) {
		set(LOCALPART, localPart);
	}

	public String getUri() {
		return get(URI);
	}

	public KBInfoModel getKB() {
		return get(KB);
	}

	public void setKB(KBInfoModel kb) {
		set(KB, kb);
	}

	/**
	 * Checks if two resources are the same
	 * They are only the same if their URIs and the KBs to which they are associated match.
	 */
	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof KBResourceModel) || obj == null)
			return false;
		KBResourceModel res = (KBResourceModel) obj;
		if (getKB() != null) {
			return getUri().equals(res.getUri()) && getKB().equals(res.getKB());
		}
		return getUri().equals(((KBResourceModel) obj).getUri());
	}

	// Dummy Variables for GWT
	private KBAnnotationValueModel dummyAnnotationValueModel;
	private KBIndividualModel dummyIndividualModel;

	public static String getLocalPart(String uri) {
		try {
			String[] parts = uri.split("#");
			if (parts.length > 1)
				return parts[1];
			else
				return uri.substring(uri.lastIndexOf("/") + 1);
		} catch (Exception e) {
			return uri;
		}

	}

	public static String getNamespace(String uri) {
		try {
			String[] parts = uri.split("#");
			return parts[0];
		} catch (Exception e) {
			return uri;
		}

	}

	public int compareTo(KBResourceModel o) {
		return getLabel().compareTo(o.getLabel());
	}

}
